#ifndef UICONTAINER_H
#define UICONTAINER_H

#include "defines.h"
#include <string>
#include <vector>

// UI控件的基类，虚函数，需要子类实现
class UIContainer
{
  public:
    UIContainer(UIContainer *parent);
    ~UIContainer();

    // 获取控件树的根节点
    virtual UIContainer *getRoot();
    virtual DuiWinManager *getWinManager();

    // 父子关系
    virtual UIContainer *getParent();
    virtual void setParent(UIContainer *parent);

    // 子控件
    virtual void addChild(UIContainer *child);
    virtual void removeChild(UIContainer *child);
    virtual int getChildCount();
    virtual UIContainer *getChild(int index);
    virtual int getChildIndex(UIContainer *child);

    // 名称
    DEFINE_PROPERTY(std::string, Name, "UIContainer");
    // 类型
    virtual std::string getUIType() = 0;

    // 文本, 使用 UTF8 编码
    DEFINE_PROPERTY(std::wstring, TextW, L"");     // UTF16 编码
    virtual void setText(const std::string &val); // UTF8 编码, 自动从UTF16转UTF8
    virtual std::string &getText();

    // 文本对齐方式
    DEFINE_PROPERTY(DUI_TEXT_ALIGN, TextAlignX, DUI_TEXT_ALIGN_CENTER);
    DEFINE_PROPERTY(DUI_TEXT_ALIGN, TextAlignY, DUI_TEXT_ALIGN_CENTER);

    // 前景颜色, 文本颜色
    DEFINE_PROPERTY(DuiColor, Color, DuiColor{0, 0, 0, 255});

    // 是否可以编辑
    DEFINE_PROPERTY(bool, Editable, false);

    // 位置和大小
    DEFINE_PROPERTY(DuiRect, Rect, DuiRect{0, 0, 0, 0});
    virtual void setSize(int w, int h);
    virtual void setPos(int x, int y);
    // 可见性
    DEFINE_PROPERTY(bool, Visible, true);
    // 透明度
    DEFINE_PROPERTY(float, Opacity, 1.0f);
    // 背景
    DEFINE_PROPERTY(DuiColor, BackgroundColor, DuiColor{255, 255, 255, 200});
    DEFINE_PROPERTY(std::string, BackgroundImage, "");
    DEFINE_PROPERTY(DUI_IMAGE_FIT, BackgroundImageFit, DUI_IMAGE_FIT_CONTAIN);

    // 边框
    DEFINE_PROPERTY(int, BorderWidth, 0);
    DEFINE_PROPERTY(DuiColor, BorderColor, DuiColor{0, 0, 0, 255});
    DEFINE_PROPERTY(DUI_LINE_STYLE, BorderLineStyle, DUI_LINE_STYLE_SOLID);
    DEFINE_PROPERTY(int, BorderRadius, 0);
    // 边框图片
    DEFINE_PROPERTY(std::string, BorderImage, "");
    DEFINE_PROPERTY(DuiCorner, BorderImageCorner, DuiCorner{0, 0, 0, 0});

    // 阴影: x, y, blur, spread
    DEFINE_PROPERTY(DuiPoint, ShadowOffset, DuiPoint{0, 0});
    DEFINE_PROPERTY(DuiColor, ShadowColor, DuiColor{0, 0, 0, 20});

    // padding
    DEFINE_PROPERTY(DuiCorner, Padding, DuiCorner{0, 0, 0, 0});
    // margin
    DEFINE_PROPERTY(DuiCorner, Margin, DuiCorner{0, 0, 0, 0});

    // cursor
    DEFINE_PROPERTY(DUI_CURSOR_STYLE, Cursor, DUI_CURSOR_STYLE_ARROW);

    // Font
    DEFINE_PROPERTY(std::string, FontFamily, "Microsoft YaHei");
    DEFINE_PROPERTY(std::string, FontFamilyCb, "Segoe UI Emoji");
    DEFINE_PROPERTY(int, FontSize, 14);
    DEFINE_PROPERTY(DuiColor, FontColor, DuiColor{0, 0, 0, 255});
    DEFINE_PROPERTY(int, FontWeight, 400);

    // 状态
    // https://developer.mozilla.org/zh-CN/docs/Web/CSS/Pseudo-classes
    // https://blog.csdn.net/2302_80198073/article/details/137742438
    DEFINE_PROPERTY(bool, Disabled, false);
    DEFINE_PROPERTY(bool, Pressed, false);
    DEFINE_PROPERTY(bool, Actived, false);
    virtual bool isHovering();
    virtual bool isFocusing();
    virtual bool isInContainer(int x, int y);

    // user data
    DEFINE_PROPERTY_PTR(void *, UserData, nullptr);

  protected:
    UIContainer *m_Parent = nullptr;
    DuiWinManager *pWinManger = nullptr; // onDraw时候自动缓存
    std::vector<UIContainer *> children = std::vector<UIContainer *>();
    std::string m_Text; // UTF8 编码
    DuiPoint m_mousePos;

  public:
    // 绘制
    virtual void onDraw(DuiWinManager *mgr);
    DEFINE_PROPERTY(bool, NeedUpdate, true);
    virtual void onDrawContent(DuiWinManager *mgr, DuiRect& rect_in, DuiRect& rect_out) = 0;
    virtual DuiPoint getMousePos();
    
    // 事件
    virtual void onMouseDown(int x, int y);
    virtual void onMouseUp(int x, int y);
    virtual void onMouseMove(int x, int y);
    virtual void onMouseLeave();
    virtual void onMouseEnter();
    virtual void onMouseWheel(int delta, int x, int y);
    virtual void onKeyDown(int key);
    virtual void onKeyUp(int key);
    virtual void onKeyChar(int key);
    virtual void onImeChar(int key);
    virtual void onCommand(int command, void *param);
};

#endif